package mt521.cam.ac.uk;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;

import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;

public class Output {

    static float sampleRate = Encode.getSampleRate();
    static AudioFormat sound = new AudioFormat(sampleRate,8,1,true,false);
    
    public static void play(byte[] sineWave) {
        try {
            SourceDataLine sdl = AudioSystem.getSourceDataLine(sound); //like a sound buffer
            int arrayLength = sineWave.length;
            
            sdl.open(sound);
            sdl.start();
            sdl.write(sineWave,0,arrayLength);
            sdl.drain(); //need this or the sound doesn't play for the full time. "flush" doesn't work.
            sdl.close();
        }
        catch (LineUnavailableException e) {
            System.err.println("Unable to play sound, SourceDataLine error.");
        }
    }
    
    public static void save(byte[] sineWave, File fileOut, int msecs) {
        ByteArrayInputStream byteStream = new ByteArrayInputStream(sineWave);
        
        AudioFileFormat aff = new AudioFileFormat(AudioFileFormat.Type.WAVE,sound,(int)(sampleRate*msecs/1000));
        AudioFileFormat.Type fileType = aff.getType();
        AudioInputStream ais = new AudioInputStream(byteStream,sound,(long)(sampleRate*msecs/1000));
        if (AudioSystem.isFileTypeSupported(fileType,ais)) { 
            try {
                AudioSystem.write(ais, fileType, fileOut);
            }
            catch (IOException e) {
                System.err.println("Unable to write to file");
            }
        }
    }
    
    public static void saveMult(byte[][] sineWaves, File fileOut, int msecs) {
        int freqNum = sineWaves.length;
        int sineLength = sineWaves[0].length;
        AudioFileFormat aff = new AudioFileFormat(AudioFileFormat.Type.WAVE,sound,(int)(sampleRate*freqNum*msecs/1000));
        AudioFileFormat.Type fileType = aff.getType();
        
        byte[] superBuffer = new byte[sineLength*freqNum];
        for (int i=0; i<freqNum; i++) {
            for (int j=0; j<sineLength; j++) {
                superBuffer[(sineLength*i)+j] = sineWaves[i][j];
            }
        }
        
        ByteArrayInputStream byteStream = new ByteArrayInputStream(superBuffer);
        System.out.println("Total Size "+superBuffer.length);
        AudioInputStream ais = new AudioInputStream(byteStream,sound,(long)(sampleRate*freqNum*msecs/1000));
        if (AudioSystem.isFileTypeSupported(fileType,ais)) { 
            try {
                AudioSystem.write(ais, fileType, fileOut);
            }
            catch (IOException e) {
                System.err.println("Unable to write to file, make sure file is not open");
                e.printStackTrace();
            }
        }
    }

}
